/**
 * @file app_midi_stream.h
 * @brief MIDI消息队列和数据流解析器
 * @details 从CAN数据流中提取多个MIDI消息，存入队列供应用层处理
 * @version 1.0
 * @date 2025-11-04
 */

#ifndef __APP_MIDI_STREAM_H__
#define __APP_MIDI_STREAM_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "midi_parser.h"
#include <stdint.h>
#include <stdbool.h>

/* Exported constants --------------------------------------------------------*/

/**
 * @brief MIDI消息队列大小
 * @note 建议值: 16-32，根据RAM限制调整
 */
#define MIDI_QUEUE_SIZE         16

/* Exported types ------------------------------------------------------------*/

/* Exported functions prototypes ---------------------------------------------*/

/**
 * @brief 初始化MIDI消息队列和流解析器
 * @return 0成功, -1失败
 */
int app_midi_stream_init(void);

/**
 * @brief 处理CAN接收到的数据流
 * @param data CAN接收数据缓冲区
 * @param len 数据长度
 * @return 成功解析并入队的消息数量, -1失败
 *
 * @details 自动识别并拆分以下格式:
 *          - MIDI 1.0字节流 (3字节)
 *          - BLE MIDI (可变长度)
 *          - MIDI 2.0 UMP MT2 (64位)
 *          - MIDI 2.0 UMP MT4 (128位)
 *
 * @note 此函数可在CAN接收中断或任务中调用
 */
int app_midi_stream_feed(uint8_t *data, uint16_t len);

/**
 * @brief 从队列中获取一条MIDI消息
 * @param msg 输出: MIDI消息指针
 * @return true成功, false队列为空
 *
 * @note 此函数应在主循环中周期性调用
 */
bool app_midi_stream_pop(midi_message_t *msg);

/**
 * @brief 获取队列中待处理消息数量
 * @return 消息数量
 */
uint8_t app_midi_stream_get_count(void);

/**
 * @brief 检查队列是否为空
 * @return true为空, false非空
 */
bool app_midi_stream_is_empty(void);

/**
 * @brief 检查队列是否已满
 * @return true已满, false未满
 */
bool app_midi_stream_is_full(void);

/**
 * @brief 清空队列
 */
void app_midi_stream_clear(void);

/**
 * @brief MIDI消息处理任务 (主循环调用)
 * @details 从队列取出消息并调用app_midi处理
 * @note 建议在主循环中每1ms调用
 */
void app_midi_stream_process(void);

#ifdef __cplusplus
}
#endif

#endif /* __APP_MIDI_STREAM_H__ */

/******************************** 文件结束 *********************************/
